package com.mxpio.erp.sales.policy.impl;


import com.mxpio.erp.common.enums.NoticeStatusEnums;
import com.mxpio.erp.common.enums.OrderEnums;
import com.mxpio.erp.common.enums.OrderStatusEnums;
import com.mxpio.erp.common.jpa.model.Order;
import com.mxpio.erp.common.order.policy.AbstractBizOrderPolicy;
import com.mxpio.erp.common.order.policy.OrderContext;
import com.mxpio.erp.common.order.service.OrderLineService;
import com.mxpio.erp.common.quality.entity.SoInQualityOrder;
import com.mxpio.erp.common.quality.entity.SoInQualityOrderLine;
import com.mxpio.erp.common.sales.entity.*;
import com.mxpio.erp.common.vo.NoticeClassVo;
import com.mxpio.erp.common.vo.OrderExcuteLineVo;
import com.mxpioframework.jpa.JpaUtil;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 销售订单执行策略
 * @author fangsong
 *
 */
public class DefaultRejectPolicy extends AbstractBizOrderPolicy {

	private List<OrderExcuteLineVo> orderExcuteVos;
	private OrderLineService orderLineService;
	public DefaultRejectPolicy(List<OrderExcuteLineVo> orderExcuteVos, OrderLineService orderLineService) {
		this.orderExcuteVos = orderExcuteVos;
		this.orderLineService = orderLineService;
	}

	@Override
	public void execute(OrderContext context) {
	}

	@Override
	public OrderContext config(OrderContext context) {
		context.setOrderExcuteVos(orderExcuteVos);
		context.setNoticeClass(RejectBill.class);
		context.setQualityClass(RejectBill.class);//此处设置QualityClass，且和NoticeClass保持一致，防止物料供应链开启检验AbstractBizOrderPolicy逻辑中按QualityClass生成数据会报错的情况
		context.setAccessType(OrderEnums.AccessType.IN.getCode());
		context.setPickingType(NoticeStatusEnums.NoticeType.SO_IN.getCode());
		return context;
	}

	@Override
	public boolean beforeExecute(OrderContext context) {
		Order order = context.getEntity();
		if (order instanceof SalesOrder && context.getOrderExcuteVos().size()>0){
			List<OrderExcuteLineVo> orderExcuteVos = context.getOrderExcuteVos();
			List<String> orderlinesStr = orderExcuteVos.stream().map(OrderExcuteLineVo::getBizOrderlineNo).collect(Collectors.toList());
			List<SalesOrderLine> orderLines = JpaUtil.linq(SalesOrderLine.class).equal("bizNo", order.getBizNo()).in("lineNo", orderlinesStr).list();

			NoticeClassVo shippingNoticeClazz = new NoticeClassVo(ShippingNotice.class, ShippingNoticeLine.class);
			NoticeClassVo rejectBillNoticeClazz = new NoticeClassVo(RejectBill.class, RejectBillLine.class);
			NoticeClassVo inQualityOrderClazz = new NoticeClassVo(SoInQualityOrder.class, SoInQualityOrderLine.class);//增加入库验收单 数据统计
			List<NoticeClassVo> noticeClassVos = new ArrayList<NoticeClassVo>();
			noticeClassVos.add(shippingNoticeClazz);
			noticeClassVos.add(rejectBillNoticeClazz);
			noticeClassVos.add(inQualityOrderClazz);
			orderLineService.handleBizOrderLineQuantity(orderLines, noticeClassVos, OrderEnums.AccessType.OUT.getCode());
			//Map<String, List<SalesOrderLine>> map = orderLines.stream().collect(Collectors.groupingBy(SalesOrderLine::getLineNo));
			Map<String, SalesOrderLine> orderLineMap = JpaUtil.index(orderLines,"lineNo");
			for(OrderExcuteLineVo orderExcuteVo : orderExcuteVos) {
				// BigDecimal lineQuantity = orderExcuteVo.getLineQuantity();
				BigDecimal quantity = orderExcuteVo.getQuantity();
				String bizOrderlineNo = orderExcuteVo.getBizOrderlineNo();
				SalesOrderLine orderLine = orderLineMap.get(bizOrderlineNo);
				if (orderLine!=null){
					BigDecimal actualQuantity = orderLine.getActualQuantity();
					BigDecimal actualRejectQuantity = orderLine.getActualRejectQuantity();
					//BigDecimal planQuantity = orderLine.getPlanQuantity();
					BigDecimal planRejectQuantity = orderLine.getPlanRejectQuantity();
					//退货时，最大可退数量=已执行数量减去已执行退货数量减去计划退货数量，不考虑计划执行数量
					BigDecimal lastMax = actualQuantity.subtract(actualRejectQuantity).subtract(planRejectQuantity);
					if (quantity.compareTo(lastMax)>0){
						context.addError("提交数据中行号【"+bizOrderlineNo+"】执行数量大于最大可执行数量【"+lastMax+"】。");
						return false;
					}
				}
			}
		}
		return true;
	}

	@Override
	public void afterExecute(OrderContext context) {
		//更新状态
		Order order = context.getEntity();
		if(OrderStatusEnums.OrderStatus.FINISHED.getStatusCode().equals(order.getOrderStatus())) {//执行退货操作时，如果订单状态是完成，则需要更新为执行中。
			order.setOrderStatus(OrderStatusEnums.OrderStatus.PROCESSING.getStatusCode());
			//order.setExecuteTime(new Date());
			JpaUtil.update(order);
		}
	}

}
